return X86EMUL_UNHANDLEABLE;
}
- curr->arch.hvm_vcpu.io_state =
- (val == NULL) ? HVMIO_dispatched : HVMIO_awaiting_completion;
-
if ( p->state != STATE_IOREQ_NONE )
+ {
gdprintk(XENLOG_WARNING, "WARNING: io already pending (%d)?\n",
p->state);
+ return X86EMUL_UNHANDLEABLE;
+ }
+
+ curr->arch.hvm_vcpu.io_state =
+ (val == NULL) ? HVMIO_dispatched : HVMIO_awaiting_completion;
p->dir = dir;
p->data_is_ptr = value_is_ptr;
break;
default:
gdprintk(XENLOG_ERR, "Weird HVM iorequest state %d.\n", p->state);
- domain_crash_synchronous();
+ domain_crash(v->domain);
+ return; /* bail */
}
}
}
p = &get_ioreq(v)->vp_ioreq;
if ( unlikely(p->state != STATE_IOREQ_NONE) )
{
- /* This indicates a bug in the device model. Crash the domain. */
+ /* This indicates a bug in the device model. Crash the domain. */
gdprintk(XENLOG_ERR, "Device model set bad IO state %d.\n", p->state);
- domain_crash_synchronous();
+ domain_crash(v->domain);
+ return;
}
prepare_wait_on_xen_event_channel(v->arch.hvm_vcpu.xen_port);
{
unsigned long data;
- switch ( p->type )
+ if ( !p->data_is_ptr )
{
- case IOREQ_TYPE_COPY:
- if ( !p->data_is_ptr ) {
- if ( p->dir == IOREQ_READ )
- p->data = read_handler(v, p->addr, p->size);
- else /* p->dir == IOREQ_WRITE */
- write_handler(v, p->addr, p->size, p->data);
- } else { /* p->data_is_ptr */
- int i, sign = (p->df) ? -1 : 1;
-
- if ( p->dir == IOREQ_READ ) {
- for ( i = 0; i < p->count; i++ ) {
- data = read_handler(v,
- p->addr + (sign * i * p->size),
- p->size);
- (void)hvm_copy_to_guest_phys(
- p->data + (sign * i * p->size),
- &data,
- p->size);
- }
- } else {/* p->dir == IOREQ_WRITE */
- for ( i = 0; i < p->count; i++ ) {
- (void)hvm_copy_from_guest_phys(
- &data,
- p->data + (sign * i * p->size),
- p->size);
- write_handler(v,
- p->addr + (sign * i * p->size),
- p->size, data);
- }
+ if ( p->dir == IOREQ_READ )
+ p->data = read_handler(v, p->addr, p->size);
+ else /* p->dir == IOREQ_WRITE */
+ write_handler(v, p->addr, p->size, p->data);
+ }
+ else
+ {
+ int i, sign = (p->df) ? -1 : 1;
+
+ if ( p->dir == IOREQ_READ )
+ {
+ for ( i = 0; i < p->count; i++ )
+ {
+ data = read_handler(
+ v,
+ p->addr + (sign * i * p->size),
+ p->size);
+ (void)hvm_copy_to_guest_phys(
+ p->data + (sign * i * p->size),
+ &data,
+ p->size);
+ }
+ }
+ else
+ {
+ for ( i = 0; i < p->count; i++ )
+ {
+ (void)hvm_copy_from_guest_phys(
+ &data,
+ p->data + (sign * i * p->size),
+ p->size);
+ write_handler(
+ v,
+ p->addr + (sign * i * p->size),
+ p->size, data);
}
}
- break;
-
- default:
- printk("hvm_mmio_access: error ioreq type %x\n", p->type);
- domain_crash_synchronous();
- break;
}
}
void send_invalidate_req(void)
{
struct vcpu *v = current;
- vcpu_iodata_t *vio;
+ vcpu_iodata_t *vio = get_ioreq(v);
ioreq_t *p;
- vio = get_ioreq(v);
- if ( vio == NULL )
- {
- printk("bad shared page: %lx\n", (unsigned long) vio);
- domain_crash_synchronous();
- }
+ BUG_ON(vio == NULL);
p = &vio->vp_ioreq;
if ( p->state != STATE_IOREQ_NONE )
- printk("WARNING: send invalidate req with something "
- "already pending (%d)?\n", p->state);
+ {
+ gdprintk(XENLOG_ERR, "WARNING: send invalidate req with something "
+ "already pending (%d)?\n", p->state);
+ domain_crash(v->domain);
+ return;
+ }
p->type = IOREQ_TYPE_INVALIDATE;
p->size = 4;
ioreq_t *p = &get_ioreq(curr)->vp_ioreq;
enum hvm_io_state io_state;
- if ( p->state != STATE_IORESP_READY )
- {
- gdprintk(XENLOG_ERR, "Unexpected HVM iorequest state %d.\n", p->state);
- domain_crash_synchronous();
- }
-
rmb(); /* see IORESP_READY /then/ read contents of ioreq */
p->state = STATE_IOREQ_NONE;
hvmemul_ctxt->insn_buf[0], hvmemul_ctxt->insn_buf[1],
hvmemul_ctxt->insn_buf[2], hvmemul_ctxt->insn_buf[3],
hvmemul_ctxt->insn_buf[4], hvmemul_ctxt->insn_buf[5]);
- domain_crash_synchronous();
+ domain_crash(curr->domain);
}
void vmx_realmode(struct cpu_user_regs *regs)
arch_vmx->vmcs = NULL;
}
-void vm_launch_fail(unsigned long eflags)
+void vm_launch_fail(void)
{
unsigned long error = __vmread(VM_INSTRUCTION_ERROR);
printk("<vm_launch_fail> error code %lx\n", error);
domain_crash_synchronous();
}
-void vm_resume_fail(unsigned long eflags)
+void vm_resume_fail(void)
{
unsigned long error = __vmread(VM_INSTRUCTION_ERROR);
printk("<vm_resume_fail> error code %lx\n", error);
/*vmx_resume:*/
HVM_RESTORE_ALL_NOSEGREGS
VMRESUME
- pushf
call vm_resume_fail
ud2
movb $1,VCPU_vmx_launched(%ebx)
HVM_RESTORE_ALL_NOSEGREGS
VMLAUNCH
- pushf
call vm_launch_fail
ud2
/*vmx_resume:*/
HVM_RESTORE_ALL_NOSEGREGS
VMRESUME
- pushfq
call vm_resume_fail
ud2
movb $1,VCPU_vmx_launched(%rbx)
HVM_RESTORE_ALL_NOSEGREGS
VMLAUNCH
- pushfq
call vm_launch_fail
ud2